package com.lnsystem.model;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.Formula;
import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GeneratorType;
@Entity
@Table(name="STOCKWEEKLY")
public class StockWeeklyData  implements StockData {

	@Id
	@Column(name="ID")
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="STOCK_WEEKLY_SEQUENCE")
	@SequenceGenerator(
		    name="STOCK_WEEKLY_SEQUENCE",
		    sequenceName="STOCK_WEEKLY_SEQUENCE",
		    allocationSize=20
		)
	private int id;

	@Column(name="SYMBOL")
	private String symbol;
	
	@ManyToOne(fetch = FetchType.LAZY,  cascade = {CascadeType.ALL})
	@JoinColumn(name = "STOCKID", nullable = false) 
	private Stock stockIdWeekly;
	
	@Column(name="OPEN")
	private double open;
	
	@Column(name="CLOSE")
	private double close;
	
	@Column(name="HIGH")
	private double high;
	
	@Column(name="LOW")
	private double low;
	
	@Column(name="PERCENTPRICECHANGE")
	private double percentPriceChange;
	
	@Column(name="PRICECHANGE")
	private double priceChange;
	
	@Column(name="VOLUME")
	private BigInteger volume;
	
	@Formula("(select avg(volume) from stockdaily sd where sd.stockid=stockid)")
	private double averageVolume;
	
	@Column(name="DATETIME")
	private Date date;
	
	// based on property/config, this list will be populated with different movingaverages
	// like 50sma, 200sma, 20sma, 10ema, 8ema, 20ema etc..
	//@OneToMany(fetch = FetchType.LAZY, mappedBy = "stockDailyData", cascade = {CascadeType.ALL})
	@Transient
	private List<MovingAverage> movingAverages; //1:n with movingAverage table

	@Transient
	private double bbUpper;
	@Transient
	private double bbMiddle;
	@Transient
	private double bbLower;
	//private TechIndicator techIndicator;
	
	@Transient
	private String notes;
	
	public StockWeeklyData() {
		this.movingAverages = new ArrayList<MovingAverage>();
	}
	
	
	public List<MovingAverage> getMovingAverages() {
		return movingAverages;
	}
	
	
	public MovingAverage getMovingAverage(int type, int period) {
		
		MovingAverage result = null;
		
		List<MovingAverage> maList = getMovingAverages();
		for(MovingAverage ma : maList ) {
			if(ma.getPeriod() == period && ma.getType()==type) {
				return ma;
			}
		}
		return result;
	}
	
	public void setMovingAverages(List<MovingAverage> movingAverages) {
		this.movingAverages = movingAverages;
	}
	

	
	
	public double getBbUpper() {
		return bbUpper;
	}


	public void setBbUpper(double bbUpper) {
		this.bbUpper = bbUpper;
	}


	public double getBbMiddle() {
		return bbMiddle;
	}


	public void setBbMiddle(double bbMiddle) {
		this.bbMiddle = bbMiddle;
	}


	public double getBbLower() {
		return bbLower;
	}


	public void setBbLower(double bbLower) {
		this.bbLower = bbLower;
	}


	public String getSymbol() {
		return symbol;
	}
	public void setSymbol(String symbol) {
		this.symbol = symbol;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Stock getStockId() {
		return stockIdWeekly;
	}
	public void setStockId(Stock stockId) {
		this.stockIdWeekly = stockId;
	}
	public double getOpen() {
		return open;
	}
	public void setOpen(double open) {
		this.open = open;
	}
	public double getClose() {
		return close;
	}
	public void setClose(double close) {
		this.close = close;
	}
	public double getHigh() {
		return high;
	}
	public void setHigh(double high) {
		this.high = high;
	}
	public double getLow() {
		return low;
	}
	public void setLow(double low) {
		this.low = low;
	}
	public BigInteger getVolume() {
		return volume;
	}
	public void setVolume(BigInteger volume) {
		this.volume = volume;
	}	
	public Date getDate() {
		return date;
	}
	public void setDate(Date date) {
		this.date = date;
	}
	
	public double getPercentPriceChange() {
		return percentPriceChange;
	}


	public void setPercentPriceChange(double percentPriceChange) {
		this.percentPriceChange = percentPriceChange;
	}


	public double getPriceChange() {
		return priceChange;
	}


	public void setPriceChange(double priceChange) {
		this.priceChange = priceChange;
	}


	public double getAverageVolume() {
		return averageVolume;
	}


	public void setAverageVolume(double averageVolume) {
		this.averageVolume = averageVolume;
	}


	public String getNotes() {
		return notes;
	}


	public void setNotes(String notes) {
		this.notes = notes;
	}


	@Override
	public String toString() {
		return "StockWeeklyData [id=" + id + ", symbol=" + symbol + ", stockId="
				+ stockIdWeekly + ", open=" + open + ", close=" + close + ", high="
				+ high + ", low=" + low + ", percentPriceChange="
				+ percentPriceChange + ", priceChange=" + priceChange
				+ ", volume=" + volume + ", averageVolume=" + averageVolume
				+ ", date=" + date + ", movingAverages=" + movingAverages
				+ ", getMovingAverages()=" + getMovingAverages()
				+ ", getSymbol()=" + getSymbol() + ", getId()=" + getId()
				+ ", getStockId()=" + getStockId() + ", getOpen()=" + getOpen()
				+ ", getClose()=" + getClose() + ", getHigh()=" + getHigh()
				+ ", getLow()=" + getLow() + ", getVolume()=" + getVolume()
				+ ", getDate()=" + getDate() + ", getPercentPriceChange()="
				+ getPercentPriceChange() + ", getPriceChange()="
				+ getPriceChange() + ", getAverageVolume()="
				+ getAverageVolume() + ", getClass()=" + getClass()
				+ ", hashCode()=" + hashCode() + ", toString()="
				+ super.toString() + "]";
	}


	/*	public TechIndicator getTechIndicator() {
		return techIndicator;
	}
	public void setTechIndicator(TechIndicator techIndicator) {
		this.techIndicator = techIndicator;
	}*/
	
	
}
